home *** CD-ROM | disk | FTP | other *** search
- /*
- * ARTA VUMeters for Macintosh
- * Malcolm Slaney
- * Advanced Technology Group
- * Apple Computer, Inc.
- * malcolm@apple.com
- * 1992-1993
- *
- * Warranty Information
- * Even though Apple has reviewed this software, Apple makes no warranty
- * or representation, either express or implied, with respect to this
- * software, its quality, accuracy, merchantability, or fitness for a
- * particular purpose. As a result, this software is provided "as is,"
- * and you, its user, are assuming the entire risk as to its quality
- * and accuracy.
- *
- * Copyright (c) 1992-1993 by Apple Computer, Inc
- * All Rights Reserved.
- */
-
- /* SoundMonitor.c */
-
- #include <DSPConstants.h>
- #include <DSPManager.h>
- #include <StandardSound.h>
- #include <Memory.h>
- #include <StdLib.h>
- #include "SoundMonitor.h"
-
- pascal void DSPMonitorTaskHandler ();
-
- /* SMOpenDSPSoundStream - Open a DSP sound stream. Return the stream
- * that is used for the Standard Sound System.
- */
- SoundStream SMOpenDSPSoundStream(){
- SoundStream sound_stream;
-
- StdSndGetIndexedStream (&sound_stream, kStdSndSystemStream);
-
- return (sound_stream);
- }
-
- /* SMOpenDSP3210 - Open a DSP client. Given a sound stream, open
- * the proper DSP device and return its parameter block. We'll need
- * this parameter block later when we want to reference it.
- */
- DSPCPUDeviceParamBlkPtr SMOpenDSP3210(sound_stream)
- SoundStream sound_stream;
- {
- DSPCPUDeviceParamBlkPtr pblock;
- OSErr err;
- int i;
-
- #ifdef DONTDO
- #define UNIMPL_TRAP_NUM 0x9F
- if (NGetTrapAddress(0xBF5, ToolTrap) ==
- NGetTrapAddress(UNIMPL_TRAP_NUM, ToolTrap)){
- DoAlert("\pCathedral Toolbox is not installed. Bye.");
- exit(1);
- }
- #endif /* DONTDO */
-
- /* Check manager version */
- if (DSPManagerVersion () != kdspManagerBuildVersion)
- return (NULL);
-
- /* Allocate memory for
- * parameter block record
- */
- pblock = (DSPCPUDeviceParamBlkPtr)NewPtr(sizeof(DSPCPUDeviceParamBlk));
- if (!pblock)
- return (NULL);
-
- /* Clear out parameter block
- * so we don't have any surprises
- */
- for (i = 0; i < sizeof(DSPCPUDeviceParamBlk); i++)
- ((char *) pblock)[i] = 0;
-
- /* Get the cpu index for
- * this particular stream
- * and stuff it into parameter
- * block.
- */
- StdSndGetStreamCPUIndex(sound_stream, 0, &(pblock->pbhDeviceIndex));
-
- /* Now get the proper DSP using
- * using the manager.
- */
- err = DSPGetIndexedCPUDevice(pblock);
- if (err != noErr)
- return (NULL);
-
- /* Open DSP device */
- pblock->pbhClientPermission = kdspReadPermission;
- BlockMove("\pFrontEnd", pblock->pbhClientName, 32);
- err = DSPOpenCPUDevice(pblock);
- if (err != noErr)
- return (NULL);
-
- return (pblock);
- }
-
- /* SMCloseDSP3210 - Close the DSP client. When we're all done we close the
- * the DSP and dispose of the parameter block.
- */
-
- long SMCloseDSP3210(pblock)
- DSPCPUDeviceParamBlkPtr pblock;
- {
- OSErr err;
- long zerror = NO_ERROR;
-
- if (pblock == NULL)
- return (ERROR);
-
- err = DSPCloseCPUDevice(pblock);
- if (err != noErr)
- zerror = ERROR;
-
- DisposPtr((Ptr) pblock);
-
- return (zerror);
- }
-
- /* SMCreateDSPMonitor - Create a sound monitor. This does the real
- * work. Given a DSP device (indicated by the parameter block) and a
- * type name we can define a DSP task and load the appropriate module.
- * The type names are defined in the DSP code as NewModule(). Currently
- * "\pMax" or "\pPower" are the only valid module types.
- *
- * Once we have the module loaded into a task we can attach it to the
- * sound stream. We use the soundStream to get access to the left and
- * right channels and we insert the new task at the location determined
- * by the streamLocation parameter.
- */
-
- DSPMonitor SMCreateDSPMonitor(dspParameterBlock, soundStream,
- monitorType, streamLocation)
- DSPCPUDeviceParamBlkPtr dspParameterBlock;
- SoundStream soundStream;
- StringPtr monitorType;
- long streamLocation;
- {
- DSPMonitor monitor;
- DSPModuleRefNum MonitorModule;
- DSPSectionRefNum sectionLeft, sectionRight, section;
- long patchPoint;
- OSErr err;
-
- /* alloc mem for monitor record */
- monitor = (DSPMonitor) NewPtr(sizeof(DSPMonitorRec));
- if (!monitor)
- return (NULL);
-
- monitor->taskRef = 0;
- monitor->dspParms = 0;
- monitor->typeName = 0;
- monitor->streamLocation = streamLocation;
- monitor->taskActive = 0;
-
- /* Create new monitor task */
- err = DSPNewTask (dspParameterBlock,
- (MessageActionProc)DSPMonitorTaskHandler,
- "\pDSPMonitorTask", &monitor->taskRef);
- if (err != noErr)
- return (NULL);
-
- /* Load monitor module */
- err = DSPLoadModule (monitorType, monitor->taskRef,
- kdspAnyPositionInsert, 0,
- &MonitorModule, 240);
- if (err != noErr)
- return (NULL);
-
- /* Connect to standard sound. Figure
- * out the AIAO buffers (sections) that
- * correspond to the left and right
- * channel. The DSP monitor which we
- * created above has two input buffers
- * that we want to connect to the
- * standard sound buffers.
- */
- StdSndGetStreamSections (soundStream, §ionLeft, §ionRight);
- DSPGetSection (MonitorModule, "\pLeft", §ion);
- err = DSPConnectSections(sectionLeft, section, kdspDirectConnection);
- if (err != noErr)
- return (NULL);
-
- DSPGetSection (MonitorModule, "\pRight", §ion);
- err = DSPConnectSections(sectionRight, section, kdspDirectConnection);
- if (err != noErr)
- return (NULL);
-
- /* Insert into standard sound
- * task list at either input
- * or output. This determines whether
- * this monitor will be monitoring the
- * microphone input or the speaker
- * output.
- */
- if (streamLocation == SMMonitorInput)
- patchPoint = kStdSndRecorder;
- else
- patchPoint = kStdSndPostProcessor;
- err = StdSndInsertTask (soundStream, monitor->taskRef, patchPoint);
- if (err != noErr)
- return (NULL);
-
- /* Get pointer to the DSP monitor
- * parameters */
- DSPGetSection(MonitorModule, "\pParams", §ion);
- DSPGetSectionData (section, (Ptr *) &(monitor->dspParms));
-
- /* set monitoring */
- monitor->taskActive = FALSE;
-
- return (monitor);
- }
-
- /*
- * SMDestroyDSPMonitor - Destroy the DSP monitor task. When all done, remove
- * and dispose the DSP task that monitors the sound stream.
- */
- long SMDestroyDSPMonitor(monitor)
- DSPMonitor monitor;
- {
- long zerror = NO_ERROR;
- OSErr err;
-
- if (monitor == NULL)
- zerror = ERROR;
-
- err = DSPRemoveTask (monitor->taskRef);
- if (err != noErr)
- zerror = ERROR;
-
- err = DSPDisposeTask (monitor->taskRef);
- if (err != noErr)
- zerror = ERROR;
-
- DisposPtr ((Ptr) monitor);
-
- return (zerror);
- }
-
- /*
- * SMStartDSPMonitor - Start a DSP task to monitor the sound.
- */
- long SMStartDSPMonitor(monitor)
- DSPMonitor monitor;
- {
- OSErr err;
-
- err = DSPSetTaskActive (monitor->taskRef);
- if (err != noErr)
- return (ERROR);
- monitor->taskActive = TRUE;
-
- return (NO_ERROR);
- }
-
- /*
- * SMStopDSPMonitor - Stop a DSP task that is monitoring the sound.
- */
- long SMStopDSPMonitor(monitor)
- DSPMonitor monitor;
- {
- OSErr err;
-
- err = DSPSetTaskInactive (monitor->taskRef);
- if (err != noErr)
- return (ERROR);
- monitor->taskActive = FALSE;
-
- return (NO_ERROR);
- }
-
- long SMSetChannel(monitor, left, right)
- DSPMonitor monitor;
- enum SMSetChannelParm left, right;
- {
- struct DSPMonitorParmStruct *dspParms = monitor->dspParms;
- /* set left and right monitoring */
- switch (left){
- case SMChannelOff: /* turn channel off */
- dspParms->monitorLeft = FALSE;
- break;
-
- case SMChannelOn: /* turn channel on */
- if (!(dspParms->monitorLeft))
- dspParms->monitorLeft = TRUE;
- break;
- case SMChannelAddClient: /* add client to left monitor */
- dspParms->monitorLeft += 1;
- break;
- case SMChannelRemoveClient: /* remove client from left monitor */
- if (dspParms->monitorLeft)
- dspParms->monitorLeft -= 1;
- break;
- default: /* SMChannelDontChange : don't
- * change channel state */
- break;
- }
-
- switch (right){
- case SMChannelOff: /* turn channel off */
- dspParms->monitorRight = FALSE;
- break;
-
- case SMChannelOn: /* turn channel on */
- if (!(dspParms->monitorRight))
- dspParms->monitorRight = TRUE;
- break;
- case SMChannelAddClient: /* add client to left monitor */
- dspParms->monitorRight += 1;
- break;
- case SMChannelRemoveClient: /* remove client from left monitor */
- if (dspParms->monitorRight)
- dspParms->monitorRight -= 1;
- break;
- default: /* SMChannelDontChange: don't
- * change channel state */
- break;
- }
-
- /* do we need to activate or deactivate task? */
- if ((dspParms->monitorLeft || dspParms->monitorRight) &&
- (monitor->taskActive == FALSE))
- return SMStartDSPMonitor(monitor);
-
- if ((dspParms->monitorLeft == FALSE) &&
- (dspParms->monitorRight == FALSE) &&
- (monitor->taskActive == TRUE))
- return SMStopDSPMonitor(monitor);
-
- return (NO_ERROR);
- }
-
- static pascal void DSPMonitorTaskHandler(){
- }
-
- /* SoundMonitor.c */
-
-